package timing.ukulele.portal.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import timing.ukulele.common.data.ResponseCode;
import timing.ukulele.common.data.ResponseData;
import timing.ukulele.data.portal.view.SysTenantUserVO;
import timing.ukulele.data.portal.view.SysTenantVO;
import timing.ukulele.persistence.service.BaseService;
import timing.ukulele.portal.convertor.TenantConvertor;
import timing.ukulele.portal.convertor.TenantUserConvertor;
import timing.ukulele.portal.mapper.SysTenantMapper;
import timing.ukulele.portal.persistent.SysTenant;
import timing.ukulele.portal.persistent.SysTenantUser;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class SysTenantService extends BaseService<SysTenantMapper, SysTenant> {

    public List<SysTenantVO> getUserTenantListByUsername(String username) {
        List<SysTenantUser> tenantList = this.getBaseMapper().selectUserTenantListByUsername(username);
        if (!CollectionUtils.isEmpty(tenantList)) {
            List<Long> tenantIds = tenantList.stream().map(SysTenantUser::getTenantId).collect(Collectors.toList());
            List<SysTenant> list = this.lambdaQuery().in(SysTenant::getId, tenantIds).list();
            if (!CollectionUtils.isEmpty(list)) {
                List<SysTenantVO> voList = TenantConvertor.INSTANCE.p2vList(list);
                return voList;
            }
        }
        return null;
    }

    public List<SysTenantVO> getUserTenantListByUserId(Long userId) {
        List<SysTenantUser> tenantList = this.getBaseMapper().selectUserTenantListByUserId(userId);
        if (!CollectionUtils.isEmpty(tenantList)) {
            List<Long> tenantIds = tenantList.stream().map(SysTenantUser::getTenantId).collect(Collectors.toList());
            List<SysTenant> list = this.lambdaQuery().in(SysTenant::getId, tenantIds).list();
            if (!CollectionUtils.isEmpty(list)) {
                List<SysTenantVO> voList = TenantConvertor.INSTANCE.p2vList(list);
                return voList;
            }
        }
        return null;
    }

    public Boolean checkUserTenant(String username, Long userId, Long tenantId) {
        if (!StringUtils.hasText(username) && userId == null)
            return false;
        Integer count = this.getBaseMapper().checkUserTenant(tenantId, userId, username);
        return count != null && count > 0;
    }

    public ResponseData<Boolean> addTenantUser(SysTenantUserVO vo) {
        ResponseData<Boolean> response = new ResponseData<>();
        List<SysTenantUser> tenantList = this.getBaseMapper().selectTenantUserList(vo.getTenantId(), vo.getUserId());
        if (CollectionUtils.isEmpty(tenantList)) {
            SysTenantUser po = TenantUserConvertor.INSTANCE.v2p(vo);
            this.getBaseMapper().addTenantUser(po);
            response.setMessage("成功");
        } else {
            response.setMessage("已加入");
        }
        response.setCode(ResponseCode.SUCCESS.getCode());
        response.setData(Boolean.TRUE);
        return response;
    }

    public void deleteTenantUser(Long userId, Long tenantId) {
        this.getBaseMapper().deleteTenantUser(userId, tenantId);
    }


    public IPage<SysTenantUserVO> getUserTenantPage(int current, int size, String username, Long userId) {
        Page<SysTenantUser> page = new Page<>(current, size);
        IPage<SysTenantUser> tenantUserPage = null;
        if (userId != null) {
            tenantUserPage = this.getBaseMapper().selectUserTenantPage(page, userId);
        } else {
            if (StringUtils.hasText(username)) {
                tenantUserPage = this.getBaseMapper().selectUserTenantPage(page, username);
            }
        }
        IPage<SysTenantUserVO> tenantUserVOPage = new Page<>(current, size);
        if (tenantUserPage == null || CollectionUtils.isEmpty(tenantUserPage.getRecords())) {
            return tenantUserVOPage;
        }
        List<SysTenantUserVO> voList = new ArrayList<>(tenantUserPage.getRecords().size());
        List<SysTenantUser> records = tenantUserPage.getRecords();
        Set<Long> tenants = records.stream().map(SysTenantUser::getTenantId).collect(Collectors.toSet());
        if (CollectionUtils.isEmpty(tenants)) {
            return tenantUserVOPage;
        }
        List<SysTenant> tenantList = this.lambdaQuery().in(SysTenant::getId, tenants).select(SysTenant::getId, SysTenant::getName).list();
        if (CollectionUtils.isEmpty(tenantList)) {
            return tenantUserVOPage;
        }
        Map<Long, SysTenant> tenantMap = tenantList.stream().collect(Collectors.toMap(SysTenant::getId, Function.identity(), (oldValue, newValue) -> newValue));
        records.forEach(po -> {
            SysTenantUserVO vo = TenantUserConvertor.INSTANCE.p2v(po);
            SysTenant tenant = tenantMap.get(po.getTenantId());
            if (tenant != null) {
                vo.setTenantName(tenant.getName());
            }
            voList.add(vo);
        });
        tenantUserVOPage.setRecords(voList);
        tenantUserVOPage.setTotal(tenantUserPage.getTotal());
        return tenantUserVOPage;
    }

    public IPage<SysTenantUserVO> getTenantUserPage(int current, int size, String username, Long tenantId) {
        Page<SysTenantUser> page = new Page<>(current, size);
        IPage<SysTenantUser> userTenantPage = null;
        if (StringUtils.hasText(username)) {
            userTenantPage = this.getBaseMapper().selectTenantUserPageWithUserName(page, tenantId, username);
        } else {
            userTenantPage = this.getBaseMapper().selectTenantUserPage(page, tenantId);
        }
        IPage<SysTenantUserVO> userTenantVOPage = new Page<>(current, size);
        if (userTenantPage == null || CollectionUtils.isEmpty(userTenantPage.getRecords())) {
            return userTenantVOPage;
        }
        List<SysTenantUserVO> voList = new ArrayList<>(userTenantPage.getRecords().size());
        userTenantPage.getRecords().forEach(po -> {
            SysTenantUserVO vo = TenantUserConvertor.INSTANCE.p2v(po);
            BeanUtils.copyProperties(po, vo);
            voList.add(vo);
        });
        userTenantVOPage.setRecords(voList);
        userTenantVOPage.setTotal(userTenantPage.getTotal());
        return userTenantVOPage;
    }

    public IPage<SysTenantVO> getPage(int current, int size, Boolean deleted, String name) {
        Page<SysTenant> page = new Page<>(current, size);
        LambdaQueryChainWrapper<SysTenant> query = this.lambdaQuery();
        if (StringUtils.hasText(name))
            query.like(SysTenant::getName, name);
        if (deleted != null) {
            query.eq(SysTenant::getDeleted, deleted);
        }
        query.orderByDesc(SysTenant::getId);
        IPage<SysTenant> iPage = query.page(page);
        Page<SysTenantVO> voPage = new Page<>(current, size);
        if (iPage != null && !CollectionUtils.isEmpty(iPage.getRecords())) {
            List<SysTenantVO> voList = new ArrayList<>(iPage.getRecords().size());
            iPage.getRecords().forEach(po -> {
                SysTenantVO vo = TenantConvertor.INSTANCE.p2v(po);
                voList.add(vo);
            });
            voPage.setRecords(voList);
            voPage.setTotal(iPage.getTotal());
        }
        return voPage;
    }
}
